package com.niiwoo.civet.mobile.controller.loan;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.account.dto.common.BankCardDTO;
import com.niiwoo.civet.account.dto.common.BankTypeDTO;
import com.niiwoo.civet.account.dto.response.GetSimpleUserBankCardResponse;
import com.niiwoo.civet.account.service.bankcard.BankCardDubboService;
import com.niiwoo.civet.mobile.vo.common.BankCardVO;
import com.niiwoo.civet.mobile.vo.common.BankTypeVO;
import com.niiwoo.civet.mobile.vo.request.LoanPreSubmitRecordSaveReqVO;
import com.niiwoo.civet.mobile.vo.request.LoanReConfirmSubmitReqVO;
import com.niiwoo.civet.mobile.vo.request.loan.*;
import com.niiwoo.civet.mobile.vo.response.loan.*;
import com.niiwoo.civet.trade.dto.request.loan.*;
import com.niiwoo.civet.trade.dto.response.loan.ConfirmResponseDTO;
import com.niiwoo.civet.trade.dto.response.loan.LoanConfigResDTO;
import com.niiwoo.civet.trade.dto.response.loan.LoanSubmitCommResDTO;
import com.niiwoo.civet.trade.enums.LoanSubmitTypeEnum;
import com.niiwoo.civet.trade.enums.ProjectTypeEnum;
import com.niiwoo.civet.trade.enums.TradeConfigEnum;
import com.niiwoo.civet.trade.service.configure.TradeConfigDubboService;
import com.niiwoo.civet.trade.service.loan.*;
import com.niiwoo.tripod.web.util.PrincipalContext;
import com.niiwoo.tripod.web.util.RequestUtil;
import com.niiwoo.tripod.web.vo.Empty;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: wuke
 * @Description:
 * @Date: Created in 15:08 2018/4/14
 */
@Slf4j
@RestController
@RequestMapping("/loan")
@Api(tags = "借款(吴科) V5.1.5", description = "/loan")
public class LoanController {

    @Reference(version = "1.0.0")
    private SpeedLoanDubboService speedLoanService;

    @Reference(version = "1.0.0")
    private LoanSubmitDubboService loanSubmitDubboService;
    
    @Reference(version = "1.0.0")
    private SmallLoanDubboService smallLoanDubboService;
    
    @Reference(version = "1.0.0")
    private SocialSecurityLoanDubboService socialSecurityLoanDubboService;
    
    @Reference(version = "1.0.0")
    private CreditCardLoanDubboService creditCardLoanDubboService;
    
    @Reference(version = "1.0.0")
    private BankCardDubboService bankCardDubboService;

    @Reference(version = "1.0.0")
    private TradeConfigDubboService tradeConfigDubboService;

    @Reference(version = "1.0.0")
    private LoanPreSubmitRecordDubboService loanPreSubmitRecordDubboService;

    private static final int PRECISION_TWO = 2;

    @PostMapping("/loanCheckForSmall")
    @ApiOperation("小易贷借款检测(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanCheckForSmall(@RequestBody @Valid LoanSubmitCommReqVO loanSubmitCommReqVO) {
        log.info("loanCheckForSmall.loanSubmitCommReqVO={}", JSON.toJSONString(loanSubmitCommReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanCheckForSmall.userId={}",userId);

        LoanSubmitCommReqDTO reqDTO = new LoanSubmitCommReqDTO();
        BeanUtils.copyProperties(loanSubmitCommReqVO,reqDTO);
        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SMALL_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanCheck(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanCheckForSmall.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanCheckForSocialSecurity")
    @ApiOperation("社保贷借款检测(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanCheckForSocialSecurity(@RequestBody @Valid LoanSubmitCommReqVO loanSubmitCommReqVO) {
        log.info("loanCheckForSocialSecurity.loanSubmitCommReqVO={}", JSON.toJSONString(loanSubmitCommReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanCheckForSocialSecurity.userId={}",userId);

        LoanSubmitCommReqDTO reqDTO = new LoanSubmitCommReqDTO();
        BeanUtils.copyProperties(loanSubmitCommReqVO,reqDTO);
        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SOCIAL_SECURITY_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanCheck(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanCheckForSocialSecurity.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanCheckForCreditCard")
    @ApiOperation("信用卡借款检测(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanCheckForCreditCard(@RequestBody @Valid LoanSubmitCommReqVO loanSubmitCommReqVO) {
        log.info("loanCheckForCreditCard.loanSubmitCommReqVO={}", JSON.toJSONString(loanSubmitCommReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanCheckForCreditCard.userId={}",userId);

        LoanSubmitCommReqDTO reqDTO = new LoanSubmitCommReqDTO();
        BeanUtils.copyProperties(loanSubmitCommReqVO,reqDTO);
        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.CREDIT_CARD_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanCheck(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanCheckForCreditCard.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanConfigForSmall")
    @ApiOperation("小易贷借款配置(吴科) V5.1.5")
    public Result<LoanConfigResVO> loanConfigForSmall() {
        String userId = PrincipalContext.getUserId();
        log.info("loanConfigForSmall.userId={}",userId);

        LoanConfigReqDTO reqDTO = new LoanConfigReqDTO();
        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SMALL_LOAN);
        LoanConfigResDTO loanConfigResDTO = loanSubmitDubboService.loanConfig(reqDTO);

        String loanConfigJsonString = JSON.toJSONString(loanConfigResDTO);
        LoanConfigResVO vo = JSON.parseObject(loanConfigJsonString,LoanConfigResVO.class);

        log.info("loanConfigForSmall.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanConfigForSocialSecurity")
    @ApiOperation("社保贷借款配置(吴科) V5.1.5")
    public Result<LoanConfigResVO> loanConfigForSocialSecurity() {
        String userId = PrincipalContext.getUserId();
        log.info("loanConfigForSocialSecurity.userId={}",userId);

        LoanConfigReqDTO reqDTO = new LoanConfigReqDTO();
        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SOCIAL_SECURITY_LOAN);
        LoanConfigResDTO loanConfigResDTO = loanSubmitDubboService.loanConfig(reqDTO);

        String loanConfigJsonString = JSON.toJSONString(loanConfigResDTO);
        LoanConfigResVO vo = JSON.parseObject(loanConfigJsonString,LoanConfigResVO.class);

        log.info("loanConfigForSocialSecurity.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanConfigForCreditCard")
    @ApiOperation("信用卡借款配置(吴科) V5.1.5")
    public Result<LoanConfigResVO> loanConfigForCreditCard() {
        String userId = PrincipalContext.getUserId();
        log.info("loanConfigForCreditCard.userId={}",userId);

        LoanConfigReqDTO reqDTO = new LoanConfigReqDTO();
        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.CREDIT_CARD_LOAN);
        LoanConfigResDTO loanConfigResDTO = loanSubmitDubboService.loanConfig(reqDTO);

        String loanConfigJsonString = JSON.toJSONString(loanConfigResDTO);
        LoanConfigResVO vo = JSON.parseObject(loanConfigJsonString,LoanConfigResVO.class);

        log.info("loanConfigForCreditCard.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanSubmitForSmall")
    @ApiOperation("小易贷申请极速借借款(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanSubmitForSmall(@RequestBody @Valid LoanSubmitReqVO loanSubmitReqVO, HttpServletRequest request) {
        log.info("loanSubmitForSmall.loanSubmitReqVO={}",JSON.toJSONString(loanSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanSubmitForSmall.userId={}",userId);

        String userRealIP = RequestUtil.getUserRealIP(request);

        String reqVOJSONString = JSON.toJSONString(loanSubmitReqVO);
        LoanSubmitReqDTO reqDTO = JSON.parseObject(reqVOJSONString, LoanSubmitReqDTO.class);
        reqDTO.getDeviceInfo().setIp(userRealIP);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SMALL_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanSubmitForSmall.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanSubmitForSocialSecurity")
    @ApiOperation("社保贷申请极速借借款(吴科)")
    public Result<LoanSubmitCommResVO> loanSubmitForSocialSecurity(@RequestBody @Valid LoanSubmitReqVO loanSubmitReqVO, HttpServletRequest request) {
        log.info("loanSubmitForSocialSecurity.loanSubmitReqVO={}",JSON.toJSONString(loanSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanSubmitForSocialSecurity.userId={}",userId);

        String userRealIP = RequestUtil.getUserRealIP(request);

        String reqVOJSONString = JSON.toJSONString(loanSubmitReqVO);
        LoanSubmitReqDTO reqDTO = JSON.parseObject(reqVOJSONString, LoanSubmitReqDTO.class);
        reqDTO.getDeviceInfo().setIp(userRealIP);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SOCIAL_SECURITY_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanSubmitForSocialSecurity.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanSubmitForCreditCard")
    @ApiOperation("信用卡申请极速借借款(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanSubmitForCreditCard(@RequestBody @Valid LoanSubmitReqVO loanSubmitReqVO, HttpServletRequest request) {
        log.info("loanSubmitForCreditCard.loanSubmitReqVO={}",JSON.toJSONString(loanSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanSubmitForCreditCard.userId={}",userId);

        String userRealIP = RequestUtil.getUserRealIP(request);

        String reqVOJSONString = JSON.toJSONString(loanSubmitReqVO);
        LoanSubmitReqDTO reqDTO = JSON.parseObject(reqVOJSONString, LoanSubmitReqDTO.class);
        reqDTO.getDeviceInfo().setIp(userRealIP);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.CREDIT_CARD_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanSubmitForCreditCard.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanBackSubmitForSmall")
    @ApiOperation("小易贷退回标的重新提交(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanBackSubmitForSmall(@RequestBody @Valid LoanBackSubmitReqVO loanBackSubmitReqVO, HttpServletRequest request) {
        log.info("loanBackSubmitForSmall.loanSubmitReqVO={}",JSON.toJSONString(loanBackSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanBackSubmitForSmall.userId={}",userId);

        String userRealIP = RequestUtil.getUserRealIP(request);

        String reqVOJSONString = JSON.toJSONString(loanBackSubmitReqVO);
        LoanBackSubmitReqDTO reqDTO = JSON.parseObject(reqVOJSONString, LoanBackSubmitReqDTO.class);
        reqDTO.getDeviceInfo().setIp(userRealIP);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SMALL_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanBackSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanBackSubmitForSmall.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanBackSubmitForSocialSecurity")
    @ApiOperation("社保贷退回标的重新提交(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanBackSubmitForSocialSecurity(@RequestBody @Valid LoanBackSubmitReqVO loanBackSubmitReqVO, HttpServletRequest request) {
        log.info("loanBackSubmitForSocialSecurity.loanSubmitReqVO={}",JSON.toJSONString(loanBackSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanBackSubmitForSocialSecurity.userId={}",userId);

        String userRealIP = RequestUtil.getUserRealIP(request);

        String reqVOJSONString = JSON.toJSONString(loanBackSubmitReqVO);
        LoanBackSubmitReqDTO reqDTO = JSON.parseObject(reqVOJSONString, LoanBackSubmitReqDTO.class);
        reqDTO.getDeviceInfo().setIp(userRealIP);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SOCIAL_SECURITY_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanBackSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanBackSubmitForSocialSecurity.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanBackSubmitForCreditCard")
    @ApiOperation("信用卡贷退回标的重新提交(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanBackSubmitForCreditCard(@RequestBody @Valid LoanBackSubmitReqVO loanBackSubmitReqVO, HttpServletRequest request) {
        log.info("loanBackSubmitForCreditCard.loanSubmitReqVO={}",JSON.toJSONString(loanBackSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanBackSubmitForCreditCard.userId={}",userId);

        String userRealIP = RequestUtil.getUserRealIP(request);

        String reqVOJSONString = JSON.toJSONString(loanBackSubmitReqVO);
        LoanBackSubmitReqDTO reqDTO = JSON.parseObject(reqVOJSONString, LoanBackSubmitReqDTO.class);
        reqDTO.getDeviceInfo().setIp(userRealIP);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.CREDIT_CARD_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanBackSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanBackSubmitForCreditCard.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanAuditConfirmForSocialSecurity")
    @ApiOperation("社保贷确认借款(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanAuditConfirmForSocialSecurity(@RequestBody @Valid LoanAuditConfirmReqVO loanAuditConfirmReqVO) {
        log.info("loanAuditConfirmForSocialSecurity.loanAuditConfirmReqVO={}",JSON.toJSONString(loanAuditConfirmReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanAuditConfirmForSocialSecurity.userId={}",userId);

        LoanAuditConfirmReqDTO reqDTO = new LoanAuditConfirmReqDTO();
        BeanUtils.copyProperties(loanAuditConfirmReqVO,reqDTO);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SOCIAL_SECURITY_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanAuditConfirm(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanAuditConfirmForSocialSecurity.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanAuditConfirmForCreditCard")
    @ApiOperation("信用卡贷确认借款(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanAuditConfirmForCreditCard(@RequestBody @Valid LoanAuditConfirmReqVO loanAuditConfirmReqVO) {
        log.info("loanAuditConfirmForCreditCard.loanAuditConfirmReqVO={}",JSON.toJSONString(loanAuditConfirmReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanAuditConfirmForCreditCard.userId={}",userId);

        LoanAuditConfirmReqDTO reqDTO = new LoanAuditConfirmReqDTO();
        BeanUtils.copyProperties(loanAuditConfirmReqVO,reqDTO);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.CREDIT_CARD_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanAuditConfirm(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanAuditConfirmForCreditCard.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanAuditConfirmForSmall")
    @ApiOperation("小易贷确认借款(吴科) V5.1.5")
    public Result<LoanSubmitCommResVO> loanAuditConfirmForSmall(@RequestBody @Valid LoanAuditConfirmReqVO loanAuditConfirmReqVO) {
        log.info("loanAuditConfirmForSmall.loanAuditConfirmReqVO={}",JSON.toJSONString(loanAuditConfirmReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanAuditConfirmForSmall.userId={}",userId);

        LoanAuditConfirmReqDTO reqDTO = new LoanAuditConfirmReqDTO();
        BeanUtils.copyProperties(loanAuditConfirmReqVO,reqDTO);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SMALL_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanAuditConfirm(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanAuditConfirmForSmall.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    private LoanSubmitCommResVO obtainLoanSubmitCommResVO(LoanSubmitCommResDTO resDTO){
        LoanSubmitCommResVO resVO = new LoanSubmitCommResVO();
        BeanUtils.copyProperties(resDTO, resVO);
        resVO.setCheckStatus(resDTO.getStatus());
        return resVO;
    }

    @PostMapping("/smallLoan/costCalculation")
    @ApiOperation("小易贷借款费用计算-周林泉 V5.1.5")
    public Result<LoanFeeCalculationResponseVO> smallLoanCostCalculation(@RequestBody @Valid LoanFeeCalculationRequestDTO request) {
        log.info("小易贷借款费用计算"+JSONObject.toJSONString(request));
        String userId = String.valueOf(PrincipalContext.getUserId());
        //转换vo成dto给业务使用
        ConfirmLoanRequestDTO loanConfirmRequestDTO = new ConfirmLoanRequestDTO();
        loanConfirmRequestDTO.setUserId(userId);
        loanConfirmRequestDTO.setLoanAmount(request.getLoanAmount());
        loanConfirmRequestDTO.setLoanTerm(request.getLoanTerm());
        loanConfirmRequestDTO.setLoanUsage(request.getLoanUsage());
        loanConfirmRequestDTO.setConfigType(ProjectTypeEnum.SMALL_LOAN.getValue()); //8-小易贷
        //调用dubbo接口
        ConfirmResponseDTO loanConfirmResponseDTO = smallLoanDubboService.calculateCost(loanConfirmRequestDTO);
        
        //绑定的银行卡信息
        BankCardDTO bankCardDTO = bankCardDubboService.getUserBankCardInfo(userId);
        
        //封装vo接口返回给前台展示
        LoanFeeCalculationResponseVO loanFeeCalculationResponseVO = new LoanFeeCalculationResponseVO();
        loanFeeCalculationResponseVO.setHandAmount(loanConfirmResponseDTO.getHandAmount());
        loanFeeCalculationResponseVO.setPlatformManagerFee(loanConfirmResponseDTO.getPlatformManageFee());
        loanFeeCalculationResponseVO.setGuaranteServiceFee(loanConfirmResponseDTO.getGuaranteServiceFee());
        loanFeeCalculationResponseVO.setLoanInterest(loanConfirmResponseDTO.getLoanInterestFee());
        loanFeeCalculationResponseVO.setBorrowerRate(loanConfirmResponseDTO.getLoanInterestRate());
        loanFeeCalculationResponseVO.setLoanTerm(loanConfirmResponseDTO.getLoanTerm());
        loanFeeCalculationResponseVO.setRepaymentTotalAmount(loanConfirmResponseDTO.getTotalRepayAmount());
        loanFeeCalculationResponseVO.setRepaymentWay(loanConfirmResponseDTO.getRepaymentWay().getValue());
        loanFeeCalculationResponseVO.setOverdueFeeRate(loanConfirmResponseDTO.getOverdueFeeRate());
        loanFeeCalculationResponseVO.setPlatformManageFeeRate(loanConfirmResponseDTO.getPlatformManageFeeRate());
        loanFeeCalculationResponseVO.setGuaranteeServiceFeeRate(loanConfirmResponseDTO.getGuaranteeServiceFeeRate());
        loanFeeCalculationResponseVO.setBankCard(transToBankCardVO(bankCardDTO));

        return Result.with(loanFeeCalculationResponseVO);
    }
    
    private BankCardVO transToBankCardVO(BankCardDTO dto) {
        BankTypeDTO bankTypeDTO = dto.getBankType();
        BankTypeVO bankTypeVO = new BankTypeVO();
        bankTypeVO.setBankTypeId(bankTypeDTO.getBankTypeId());
        bankTypeVO.setBankCode(bankTypeDTO.getBankCode());
        bankTypeVO.setBankName(bankTypeDTO.getBankName());

        BankCardVO vo = new BankCardVO();
        vo.setBankCardId(dto.getBankCardId());
        vo.setBankAccountNo(dto.getBankAccountNo());
        vo.setBankType(bankTypeVO);

        return vo;
    }

    @PostMapping("/socialLoan/costCalculation")
    @ApiOperation("社保贷借款费用计算-周林泉 V5.1.5")
    public Result<LoanFeeCalculationResponseVO> socialSecurityLoanCostCalculation(@RequestBody @Valid LoanFeeCalculationRequestDTO request) {
        log.info("社保贷借款费用计算"+JSONObject.toJSONString(request));
        String userId = String.valueOf(PrincipalContext.getUserId());
        //转换vo成dto给业务使用
        ConfirmLoanRequestDTO loanConfirmRequestDTO = new ConfirmLoanRequestDTO();
        loanConfirmRequestDTO.setUserId(userId);
        loanConfirmRequestDTO.setLoanAmount(request.getLoanAmount());
        loanConfirmRequestDTO.setLoanTerm(request.getLoanTerm());
        loanConfirmRequestDTO.setLoanUsage(request.getLoanUsage());
        loanConfirmRequestDTO.setConfigType(ProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue()); //9-社保贷
        //调用dubbo接口
        ConfirmResponseDTO loanConfirmResponseDTO = socialSecurityLoanDubboService.calculateCost(loanConfirmRequestDTO);
        //绑定的银行卡信息
        BankCardDTO bankCardDTO = bankCardDubboService.getUserBankCardInfo(userId);
        //封装vo接口返回给前台展示
        LoanFeeCalculationResponseVO loanFeeCalculationResponseVO = new LoanFeeCalculationResponseVO();
        loanFeeCalculationResponseVO.setHandAmount(loanConfirmResponseDTO.getHandAmount());
        loanFeeCalculationResponseVO.setPlatformManagerFee(loanConfirmResponseDTO.getPlatformManageFee());
        loanFeeCalculationResponseVO.setGuaranteServiceFee(loanConfirmResponseDTO.getGuaranteServiceFee());
        loanFeeCalculationResponseVO.setLoanInterest(loanConfirmResponseDTO.getLoanInterestFee());
        loanFeeCalculationResponseVO.setBorrowerRate(loanConfirmResponseDTO.getLoanInterestRate());
        loanFeeCalculationResponseVO.setLoanTerm(loanConfirmResponseDTO.getLoanTerm());
        loanFeeCalculationResponseVO.setRepaymentTotalAmount(loanConfirmResponseDTO.getTotalRepayAmount());
        loanFeeCalculationResponseVO.setRepaymentWay(loanConfirmResponseDTO.getRepaymentWay().getValue());
        loanFeeCalculationResponseVO.setOverdueFeeRate(loanConfirmResponseDTO.getOverdueFeeRate());
        loanFeeCalculationResponseVO.setPlatformManageFeeRate(loanConfirmResponseDTO.getPlatformManageFeeRate());
        loanFeeCalculationResponseVO.setGuaranteeServiceFeeRate(loanConfirmResponseDTO.getGuaranteeServiceFeeRate());
        loanFeeCalculationResponseVO.setBankCard(transToBankCardVO(bankCardDTO));

        return Result.with(loanFeeCalculationResponseVO);
    }

    @PostMapping("/creditCard/costCalculation")
    @ApiOperation("信用卡贷借款费用计算-周林泉 V5.1.5")
    public Result<LoanFeeCalculationResponseVO> creditCardLoanCostCalculation(@RequestBody @Valid LoanFeeCalculationRequestDTO request) {
        log.info("信用卡贷借款费用计算"+JSONObject.toJSONString(request));
        String userId = String.valueOf(PrincipalContext.getUserId());
        //转换vo成dto给业务使用
        ConfirmLoanRequestDTO loanConfirmRequestDTO = new ConfirmLoanRequestDTO();
        loanConfirmRequestDTO.setUserId(userId);
        loanConfirmRequestDTO.setLoanAmount(request.getLoanAmount());
        loanConfirmRequestDTO.setLoanTerm(request.getLoanTerm());
        loanConfirmRequestDTO.setLoanUsage(request.getLoanUsage());
        loanConfirmRequestDTO.setConfigType(ProjectTypeEnum.CREDIT_CARD_LOAN.getValue()); //10-信用卡贷
        //调用dubbo接口
        ConfirmResponseDTO loanConfirmResponseDTO = creditCardLoanDubboService.calculateCost(loanConfirmRequestDTO);
        //绑定的银行卡信息
        BankCardDTO bankCardDTO = bankCardDubboService.getUserBankCardInfo(userId);
        //封装vo接口返回给前台展示
        LoanFeeCalculationResponseVO loanFeeCalculationResponseVO = new LoanFeeCalculationResponseVO();
        loanFeeCalculationResponseVO.setHandAmount(loanConfirmResponseDTO.getHandAmount());
        loanFeeCalculationResponseVO.setPlatformManagerFee(loanConfirmResponseDTO.getPlatformManageFee());
        loanFeeCalculationResponseVO.setGuaranteServiceFee(loanConfirmResponseDTO.getGuaranteServiceFee());
        loanFeeCalculationResponseVO.setLoanInterest(loanConfirmResponseDTO.getLoanInterestFee());
        loanFeeCalculationResponseVO.setBorrowerRate(loanConfirmResponseDTO.getLoanInterestRate());
        loanFeeCalculationResponseVO.setLoanTerm(loanConfirmResponseDTO.getLoanTerm());
        loanFeeCalculationResponseVO.setRepaymentTotalAmount(loanConfirmResponseDTO.getTotalRepayAmount());
        loanFeeCalculationResponseVO.setRepaymentWay(loanConfirmResponseDTO.getRepaymentWay().getValue());
        loanFeeCalculationResponseVO.setOverdueFeeRate(loanConfirmResponseDTO.getOverdueFeeRate());
        loanFeeCalculationResponseVO.setPlatformManageFeeRate(loanConfirmResponseDTO.getPlatformManageFeeRate());
        loanFeeCalculationResponseVO.setGuaranteeServiceFeeRate(loanConfirmResponseDTO.getGuaranteeServiceFeeRate());
        loanFeeCalculationResponseVO.setWithdrawFee(loanConfirmResponseDTO.getWithdrawFee());
        loanFeeCalculationResponseVO.setWithdrawFeeRate(loanConfirmResponseDTO.getWithdrawFeeRate());
        loanFeeCalculationResponseVO.setBankCard(transToBankCardVO(bankCardDTO));

        return Result.with(loanFeeCalculationResponseVO);
    }
    
    @PostMapping("/loanSuccessShowOrderInfo")
    @ApiOperation("借款成功之后展示相关借款信息(周林泉) V5.1.5")
    public Result<LoanSuccessShowOrderInfoResVO> loanSuccessShowOrderInfo(@RequestBody @Valid LoanSuccessShowOrderInfoReqVO loanSuccessShowOrderInfoReqVO, HttpServletRequest request) {
        String userId = String.valueOf(PrincipalContext.getUserId());

        //银行卡信息
        BankCardDTO bankCardDTO = bankCardDubboService.getUserBankCardInfo(userId);
        
        //提现费率和提现费用
        GetSimpleUserBankCardResponse serviceResponse = bankCardDubboService.getSimpleUserBankCard(userId);
        
        List<TradeConfigEnum> enumList = new ArrayList<>();
        enumList.add(TradeConfigEnum.FASTWITHDRAWFEE); //提现费率-快速提现
        enumList.add(TradeConfigEnum.APPLYLOANSUCCESSPROMPTSTATUS); //借款申请成功页面提示框开关
        enumList.add(TradeConfigEnum.APPLYLOANSUCCESSLINKURL); //借款申请成功页面提示框跳转链接
        Map<String, String> configMap = tradeConfigDubboService.selectTradeConfigByEmuns(enumList);
        
        LoanSuccessShowOrderInfoResVO vo = new LoanSuccessShowOrderInfoResVO();
        vo.setBankCard(transToBankCardVO(bankCardDTO));
        vo.setHasRebindApply(serviceResponse.isHasRebindApply());
        vo.setWithdrawFee(new BigDecimal(0));
        vo.setWithdrawFeeRate(new BigDecimal(0));
        vo.setApplyLoanSuccessPromptStatus(0);
        if (configMap.containsKey(TradeConfigEnum.FASTWITHDRAWFEE.getConfigKey())) {
        	BigDecimal withdrawFeeRate = new BigDecimal(configMap.get(TradeConfigEnum.FASTWITHDRAWFEE.getConfigKey()));
        	BigDecimal withdrawFee = loanSuccessShowOrderInfoReqVO.getLoanAmount().multiply(withdrawFeeRate);

        	vo.setWithdrawFeeRate(withdrawFeeRate);
        	vo.setWithdrawFee(withdrawFee.setScale(PRECISION_TWO, BigDecimal.ROUND_HALF_UP));
        }
        
        if (configMap.containsKey(TradeConfigEnum.APPLYLOANSUCCESSPROMPTSTATUS.getConfigKey())) {
        	String applyLoanSuccessPromptStatus = configMap.get(TradeConfigEnum.APPLYLOANSUCCESSPROMPTSTATUS.getConfigKey());
        	String applyLoanSuccessLinkUrl = configMap.get(TradeConfigEnum.APPLYLOANSUCCESSLINKURL.getConfigKey());

        	vo.setApplyLoanSuccessPromptStatus(Integer.valueOf(applyLoanSuccessPromptStatus));
        	vo.setApplyLoanSuccessLinkUrl(applyLoanSuccessLinkUrl);
        }
        
        return Result.with(vo);
    }

    @PostMapping("/smallLoanRepaymentPlan")
    @ApiOperation("小易贷借款确认展示还款详情(李健) V5.1.5")
    public Result<List<RepaymentPlanResponseVO>> smallLoanRepaymentPlan(@RequestBody @Valid LoanRepaymentPlanRequestDTO request) {
        log.info("小易贷借款确认展示还款详情, request={}", JSONObject.toJSONString(request));
        String userId = String.valueOf(PrincipalContext.getUserId());
        ConfirmLoanRepaymentPlanRequestDTO loanConfirmRequestDTO =
                new ConfirmLoanRepaymentPlanRequestDTO(request.getLoanAmount(), request.getLoanTerm(), userId, ProjectTypeEnum.SMALL_LOAN.getValue());
        // 计算还款计划
        List<RepaymentPlanDTO> repaymentPlanDTOList = speedLoanService.repaymentPlan(loanConfirmRequestDTO);

        return Result.with(repaymentPlanDTOTransform(repaymentPlanDTOList));
    }

    @PostMapping("/socialSecurityLoanRepaymentPlan")
    @ApiOperation("社保贷借款确认展示还款详情(李健) V5.1.5")
    public Result<List<RepaymentPlanResponseVO>> socialSecurityLoanRepaymentPlan(@RequestBody @Valid LoanRepaymentPlanRequestDTO request) {
        log.info("社保贷款确认展示还款详情, request={}", JSONObject.toJSONString(request));
        String userId = String.valueOf(PrincipalContext.getUserId());
        ConfirmLoanRepaymentPlanRequestDTO loanConfirmRequestDTO =
                new ConfirmLoanRepaymentPlanRequestDTO(request.getLoanAmount(), request.getLoanTerm(), userId, ProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue());
        // 计算还款计划
        List<RepaymentPlanDTO> repaymentPlanDTOList = speedLoanService.repaymentPlan(loanConfirmRequestDTO);

        return Result.with(repaymentPlanDTOTransform(repaymentPlanDTOList));

    }

    @PostMapping("/creditCardLoanRepaymentPlan")
    @ApiOperation("信用卡贷借款确认展示还款详情(李健) V5.1.5")
    public Result<List<RepaymentPlanResponseVO>> creditCardLoanRepaymentPlan(@RequestBody @Valid LoanRepaymentPlanRequestDTO request) {
        log.info("信用卡贷借款确认展示还款详情, request={}", JSONObject.toJSONString(request));
        String userId = String.valueOf(PrincipalContext.getUserId());
        ConfirmLoanRepaymentPlanRequestDTO loanConfirmRequestDTO =
                new ConfirmLoanRepaymentPlanRequestDTO(request.getLoanAmount(), request.getLoanTerm(), userId, ProjectTypeEnum.CREDIT_CARD_LOAN.getValue());
        // 计算还款计划
        List<RepaymentPlanDTO> repaymentPlanDTOList = speedLoanService.repaymentPlan(loanConfirmRequestDTO);

        return Result.with(repaymentPlanDTOTransform(repaymentPlanDTOList));
    }

    private List<RepaymentPlanResponseVO> repaymentPlanDTOTransform(List<RepaymentPlanDTO> repaymentPlanDTOList) {
        List<RepaymentPlanResponseVO> repaymentPlanList = null;
        if(CollectionUtils.isNotEmpty(repaymentPlanDTOList)) {
            repaymentPlanList = new ArrayList<>(repaymentPlanDTOList.size());
            for(RepaymentPlanDTO repaymentPlanDTO : repaymentPlanDTOList) {
                RepaymentPlanResponseVO planResponseVO = new RepaymentPlanResponseVO();
                BeanUtils.copyProperties(repaymentPlanDTO, planResponseVO);
                repaymentPlanList.add(planResponseVO);
            }
        }
        return repaymentPlanList;
    }

    @PostMapping("/loanReConfirmSubmitForSmall")
    @ApiOperation("小易贷提额重新确认申请极速借借款(吴科) V5.2.0")
    public Result<LoanSubmitCommResVO> loanReConfirmSubmitForSmall(@RequestBody @Valid LoanReConfirmSubmitReqVO loanReConfirmSubmitReqVO) {
        log.info("loanReConfirmSubmitForSmall.loanReConfirmSubmitReqVO={}",JSON.toJSONString(loanReConfirmSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanReConfirmSubmitForSmall.userId={}",userId);

        LoanReConfirmSubmitReqDTO reqDTO = new LoanReConfirmSubmitReqDTO();
        BeanUtils.copyProperties(loanReConfirmSubmitReqVO,reqDTO);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SMALL_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanReConfirmSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanReConfirmSubmitForSmall.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanReConfirmSubmitForSocialSecurity")
    @ApiOperation("社保贷提额重新确认申请极速借借款(吴科) V5.2.0")
    public Result<LoanSubmitCommResVO> loanReConfirmSubmitForSocialSecurity(@RequestBody @Valid LoanReConfirmSubmitReqVO loanReConfirmSubmitReqVO) {
        log.info("loanReConfirmSubmitForSocialSecurity.loanReConfirmSubmitReqVO={}",JSON.toJSONString(loanReConfirmSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanReConfirmSubmitForSocialSecurity.userId={}",userId);

        LoanReConfirmSubmitReqDTO reqDTO = new LoanReConfirmSubmitReqDTO();
        BeanUtils.copyProperties(loanReConfirmSubmitReqVO,reqDTO);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.SOCIAL_SECURITY_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanReConfirmSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanReConfirmSubmitForSocialSecurity.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanReConfirmSubmitForCreditCard")
    @ApiOperation("信用卡提额重新确认申请极速借借款(吴科) V5.2.0")
    public Result<LoanSubmitCommResVO> loanReConfirmSubmitForCreditCard(@RequestBody @Valid LoanReConfirmSubmitReqVO loanReConfirmSubmitReqVO) {
        log.info("loanReConfirmSubmitForSocialSecurity.loanReConfirmSubmitReqVO={}",JSON.toJSONString(loanReConfirmSubmitReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanReConfirmSubmitForSocialSecurity.userId={}",userId);

        LoanReConfirmSubmitReqDTO reqDTO = new LoanReConfirmSubmitReqDTO();
        BeanUtils.copyProperties(loanReConfirmSubmitReqVO,reqDTO);

        reqDTO.setUserId(userId);
        reqDTO.setLoanSubmitTypeEnum(LoanSubmitTypeEnum.CREDIT_CARD_LOAN);
        LoanSubmitCommResDTO resDTO = loanSubmitDubboService.loanReConfirmSubmit(reqDTO);
        LoanSubmitCommResVO vo = this.obtainLoanSubmitCommResVO(resDTO);

        log.info("loanReConfirmSubmitForSocialSecurity.userId={},vo={}",userId,JSON.toJSONString(vo));
        return Result.with(vo);
    }

    @PostMapping("/loanPreSubmitRecordSave")
    @ApiOperation("借款预发布日志记录保存(吴科) V5.2.0")
    public Empty loanPreSubmitRecordSave(@RequestBody @Valid LoanPreSubmitRecordSaveReqVO loanPreSubmitRecordSaveReqVO) {
        log.info("loanPreSubmitRecordSave.loanPreSubmitRecordSaveReqVO={}",JSON.toJSONString(loanPreSubmitRecordSaveReqVO));
        String userId = String.valueOf(PrincipalContext.getUserId());
        log.info("loanPreSubmitRecordSave.userId={}",userId);

        LoanPreSubmitRecordSaveReqDTO reqDTO = new LoanPreSubmitRecordSaveReqDTO();
        BeanUtils.copyProperties(loanPreSubmitRecordSaveReqVO,reqDTO);
        reqDTO.setUserId(userId);
        reqDTO.setProjectTypeEnum(ProjectTypeEnum.getEnum(loanPreSubmitRecordSaveReqVO.getProjectType()));
        loanPreSubmitRecordDubboService.loanPreSubmitRecordSave(reqDTO);

        log.info("loanPreSubmitRecordSave.userId={} end",userId);
        return Empty.getInstance();
    }
}
